/**
 * 
 */
package com.kth.subtranslator.driver;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.Set;

import com.javanetworkframework.rb.com.freetranslation.FreeTranslationTranslatorRB;
import com.javanetworkframework.rb.util.AbstractWebTranslator;
import com.kth.subtranslator.IBatchTranslateCallBack;
import com.kth.subtranslator.ITranslateDriverConfiguration;
import com.kth.subtranslator.TranslateEngine.Language;

/**
 * @author Kevin Thackray
 *
 */
public class WebTranslateApiDriver extends AbstractTranslateDriver {

	private static final String SPERATOR = "<separator>";
	
	private class WebTranslateApiDriverConfiguration implements ITranslateDriverConfiguration {
		
		private List<String> drivers = new ArrayList<String>();
		
		private Map<String, Object> options = new HashMap<String, Object>();
		
		/**
		 * 
		 */
		public WebTranslateApiDriverConfiguration() {
//			drivers.add("com.javanetworkframework.rb.com.freetranslation.FreeTranslationTranslatorRB");
//			drivers.add("com.javanetworkframework.rb.com.altavista.AltaVistaTranslatorRB");
//			drivers.add("com.javanetworkframework.rb.com.worldlingo.WorldLingoTranslatorRB");
			
			drivers.add("FreeTranslation");
			drivers.add("AltaVista");
			drivers.add("WorldLingo");
			
			options.put("Sites", drivers);
		}

		/* (non-Javadoc)
		 * @see com.kth.subtranslator.ITranslateDriverConfiguration#getOptions()
		 */
		@Override
		public Map<String, Object> getOptions() {
			return options;
		}
		
	}

	private final ITranslateDriverConfiguration translateDriverConfiguration;
	
	/**
	 * 
	 */
	public WebTranslateApiDriver() {
		this.translateDriverConfiguration = new WebTranslateApiDriverConfiguration();
	}

	/* (non-Javadoc)
	 * @see com.kth.subtranslator.ITranslateDriver#translate(java.lang.String, com.kth.subtranslator.TranslateEngine.Language, com.kth.subtranslator.TranslateEngine.Language)
	 */
	@Override
	public String translate(String text, Language fromLang, Language toLang) {
		return null;
	}

	/* (non-Javadoc)
	 * @see com.kth.subtranslator.ITranslateDriver#batchTranslate(java.util.Collection, com.kth.subtranslator.TranslateEngine.Language, com.kth.subtranslator.TranslateEngine.Language, com.kth.subtranslator.IBatchTranslateCallBack)
	 */
	@Override
	public Collection<String> batchTranslate(Collection<String> text,
			Language fromLang, Language toLang, IBatchTranslateCallBack callBack) {

		List<String> translatedString = new ArrayList<String>();
		Set<String> supportedLanguage = (Set<String>)FreeTranslationTranslatorRB.SgetSupportedTranslations();
		System.out.println("support language : " + supportedLanguage);
		String langStr = fromLang.getLocalCode() + "2" + toLang.getLocalCode();
		if (!supportedLanguage.contains(langStr)) {
			throw new RuntimeException("Translation not supported from " + fromLang.getName() + " to " + toLang.getName());
		}
		System.out.println("language supported");
		Locale srcLoc = new Locale(langStr.substring(0, langStr.indexOf('2')));
		Locale dstLoc = new Locale(langStr.substring(langStr.indexOf('2')+1));

		// Get resource bundle
		AbstractWebTranslator res = (AbstractWebTranslator) ResourceBundle.getBundle(
				"com.javanetworkframework.rb.com.freetranslation.FreeTranslationTranslatorRB",
				dstLoc);

		int i = 0;
		int accumlCount = 0;
		StringBuilder accumlBuffer = new StringBuilder();
		for (String string : text) {
			if (isStopped()) {
				return translatedString;
			}
			// accuml strings
			accumlBuffer.append(string).append( SPERATOR );
			accumlCount++;

			if (accumlCount >= 50) {
				// Translate text
				List<String> translatedBulk = internalTranslate(accumlBuffer.toString(), srcLoc, res);
				callBack.onBatchTranslated(translatedBulk, i);
				translatedString.addAll(translatedBulk);
				i+=accumlCount;
				accumlBuffer = new StringBuilder();
				accumlCount = 0;
			}
		}
		if (accumlCount > 0) {
			// something left
			List<String> translatedBulk = internalTranslate(accumlBuffer.toString(), srcLoc, res);
			callBack.onBatchTranslated(translatedBulk, i);
			translatedString.addAll(translatedBulk);
		}

		return translatedString;
	}

	/* (non-Javadoc)
	 * @see com.kth.subtranslator.ITranslateDriver#getSupportedLanguage()
	 */
	@Override
	public Collection<Language> getSupportedLanguage() {
		return Arrays.asList(Language.ENGLISH, Language.FRENCH, 
				Language.SPANISH, Language.DUTCH,
				Language.ITALIAN, Language.GERMAN, Language.RUSSIAN);
	}

	/* (non-Javadoc)
	 * @see com.kth.subtranslator.ITranslateDriver#getName()
	 */
	@Override
	public String getName() {
		return "FreeTranslation Translator";
	}

	private List<String> internalTranslate(String accumlBuffer, Locale srcLoc, AbstractWebTranslator res) {
		String output = res.getString(accumlBuffer, srcLoc);
		String[] splitedStrings = output.split( SPERATOR );
		List<String> translatedBulk = new ArrayList<String>();
		for (int j = 0; j < splitedStrings.length; j++) {
			translatedBulk.add( splitedStrings[j] );
		}
		System.out.println("translated - size : " + translatedBulk.size());
		return translatedBulk;
	}

	/* (non-Javadoc)
	 * @see com.kth.subtranslator.ITranslateDriver#getSupportedTargetLanguage(com.kth.subtranslator.TranslateEngine.Language)
	 */
	@Override
	public Collection<Language> getSupportedTargetLanguage(Language fromLang) {
		List<Language> supportedLang = new ArrayList<Language>();
		Set<String> supportedLanguage = (Set<String>)FreeTranslationTranslatorRB.SgetSupportedTranslations();
		for (String langStr : supportedLanguage) {
			String fromLangStr = langStr.substring(0, langStr.indexOf('2'));
			String toLangStr = langStr.substring(langStr.indexOf('2')+1);
			if (fromLangStr.equals(fromLang.getLocalCode())) {
				Language[] langs = Language.values();
				for (int i = 0; i < langs.length; i++) {
					if (langs[i].getLocalCode().equals(toLangStr)) {
						supportedLang.add(langs[i]);
					}
				}
			}
		}
		return supportedLang;
	}
	
	/* (non-Javadoc)
	 * @see com.kth.subtranslator.driver.AbstractTranslateDriver#getConfiguration()
	 */
	@Override
	public ITranslateDriverConfiguration getConfiguration() {
		return translateDriverConfiguration;
	}

}
